package com.vvv.shortlink.project.mq.producer;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.vvv.shortlink.project.dto.biz.LinkStatsRecordDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

/**
 * @author vvv
 * @date 2024/2/28 16 36
 * discription
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LinkStatsProducer {

    private final RocketMQTemplate rocketMQTemplate;

    /**
     * 发送单向消息
     *
     * @param topic            消息发送主题，用于标识同一类业务逻辑的消息
     * @param tag              消息的过滤标签，消费者可通过Tag对消息进行过滤，仅接收指定标签的消息。
     * @param keys             消息索引键，可根据关键字精确查找某条消息
     * @param messageEvent     普通消息发送事件，自定义对象，最终都会序列化为字符串
     * @return 消息发送 RocketMQ 返回结果
     */
    public void sendOneWayMessage(String topic, String tag, String keys, LinkStatsRecordDTO messageEvent) {
        if (StringUtils.isEmpty(topic)) {
            log.error("短链监控mq-> topic:{}不能为空", topic);
        }
        try {
            // 构建topic和tag
            StringBuilder destinationBuilder = StrUtil.builder().append(topic);
            if (StrUtil.isNotBlank(tag)) {
                destinationBuilder.append(":").append(tag);
            }
            // 构建message, 如果没有定义keys，则用uuid
            if (StringUtils.isEmpty(messageEvent.getKeys())) {
                if (StringUtils.isEmpty(keys)) {
                    messageEvent.setKeys(IdUtil.simpleUUID());
                } else {
                    messageEvent.setKeys(keys);
                }
            }
            Message<LinkStatsRecordDTO> message = MessageBuilder
                    .withPayload(messageEvent)
                    .setHeader(MessageConst.PROPERTY_KEYS, StringUtils.isEmpty(keys) ? messageEvent.getKeys() : keys)
                    .setHeader(MessageConst.PROPERTY_TAGS, tag)
                    .build();
            // 发送
            rocketMQTemplate.sendOneWay(
                    destinationBuilder.toString(),
                    message
            );
        } catch (Exception e) {
            log.error("[普通消息] 消息发送失败，消息体：{}", JSON.toJSONString(messageEvent), e);
        }
    }

    public void sendOneWayMessage(String topic, String tag, LinkStatsRecordDTO message) {
        sendOneWayMessage(topic, tag, null, message);
    }
}
